package com.webservice.impl.factory;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.webservice.dao.Pub;
import com.webservice.dao.PubBaseDao;
import com.webservice.service.IBaseService;
import com.webservice.utils.DateTimeTool;
import com.webservice.utils.UUIDUtil;
import com.webservice.utils.VOXMLMapping;
import com.webservice.vo.factory.OutProductVO;
import com.webservice.vo.factory.OutSeriVO;
import com.webservice.vo.factory.OutStoreAggVO;
import com.webservice.vo.impl.ReturnMsgVo;

/***
 * 厂家退货处理
 * @author Andy 处理逻辑 
 * 1.校验xml是否正确 
 * 2.解析xml转化为vo 
 * 3.记录日志信息
 * 4.校验数据
 * 5.改变库存，更改串码状态
 * 6.记录返回日志 
 * 7.返回数据
 */
@Service("F0002")
public class OutStoreService implements IBaseService {
	private static Logger logger = Logger.getLogger(OutStoreService.class);
	private static List<String> updateList=new ArrayList<String>();


	@SuppressWarnings("finally")
	@Override
	@Transactional(value = "txManager", isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = { Exception.class })
	public String returnData(String xml, PubBaseDao baseDao, String ip)throws Exception {
		updateList.clear();
		OutStoreAggVO ss = null;
		String content = null;
		String rexml = null;
		String intoUUID = UUIDUtil.getUUID();
		String outUUID = UUIDUtil.getUUID();
		// 成对标志
		String pairflag = DateTimeTool.getDateTimeString(new Date(),"yyyymmddHHmmss:sss").replace(":", "");
		try {
			ss = (OutStoreAggVO)VOXMLMapping.fromXML(xml, OutStoreAggVO.class, null);// xml解析
			Pub.insertLog(baseDao, intoUUID,ip, "12", ss.getOutcode(), xml, "into",pairflag,"0");
			// 校验数据
			rexml = checkData(ss, baseDao);
			if(null==rexml){
				if(changeStore(baseDao)){
					rexml = Pub.returnInfo(ss.getOutcode(), 0, "成功", null);
				}
			}
			Pub.insertLog(baseDao, outUUID,ip, "12", ss.getOutcode(), rexml, "out",pairflag,"1");
			ReturnMsgVo rmv =  (ReturnMsgVo) VOXMLMapping.fromXML(rexml, ReturnMsgVo.class, null);
			if(rmv.getResult() == 0){
				Pub.insertDealResultLog(baseDao, outUUID, "WMS", "B2B", "成功", "厂家退货处理成功");
			}else{
				Pub.insertDealResultLog(baseDao, outUUID, "WMS", "B2B", "处理异常", rmv.getMsg());
			}
		} catch (Exception e) {
			e.printStackTrace();
			content = "请求的xml转化错误" + e.getMessage();
			Pub.insertLog(baseDao, intoUUID,ip, "12", ss.getOutcode()==null?null:ss.getOutcode(), xml, "into",pairflag,"0");
			rexml = Pub.returnInfo(null, -1, "失败：" + content, null);
			Pub.insertLog(baseDao, outUUID, ip, "12",  ss.getOutcode()==null?null:ss.getOutcode(), rexml, "out",pairflag,"1");
			throw new Exception(rexml);
		}finally{
			return rexml;
		}
		
		
	}

	/***
	 * 检查数据
	 * @param ss
	 * @return  
	 * 仓库信息必须存在，并且不能为空  
	 * 供应商必须存在，并且不能为空  
	 * 产品必须存在，并且不能为空  产品数量不能为空，并且大于0  
	 * 串码信息不能为空
	 * @throws Exception 
	 */
	public String checkData(OutStoreAggVO ss,PubBaseDao baseDao) throws Exception {
		return checkStore(ss, baseDao);
	}
	/***
	 * 检查仓库
	 * @param ss
	 * @param baseDao
	 * @return
	 * @throws Exception
	 */
	public String checkStore(OutStoreAggVO ss,PubBaseDao baseDao) throws Exception{
		String storeCode=ss.getStorecode();
		if(null==storeCode){//仓库不能为空
			return Pub.returnInfo(ss.getOutcode(), -1, "失败：仓库信息为空", null);
		}else{//校验仓库是否存在
			String sql="select pk_store from bi_store where storecode=? and storelevel='01' ";
			Object[] parms=new Object[]{storeCode};
			logger.debug("查询sql："+Pub.logSQL(sql, parms));
			List<String> list=baseDao.getList(sql, parms, "pk_store");
			if(null==list||list.size()==0)return Pub.returnInfo(ss.getOutcode(), -1,"失败：仓库"+storeCode+"不存在", null);
			return checkSupply(ss, baseDao,storeCode);
		}
	}
	
	/***
	 * 检查供应商
	 * @param ss
	 * @param baseDao
	 * @return
	 */
	public String checkSupply(OutStoreAggVO ss,PubBaseDao baseDao,String pk_store){
		List<OutProductVO> products=ss.getProducts(); 
		if(null==products||products.size()==0)return Pub.returnInfo(ss.getOutcode(), -1, "失败：产品信息为空", null);
		for(OutProductVO product:products){
			BigDecimal supplyid=product.getSupplyid();//供应商
			String productcode=product.getProductcode();//产品
			BigDecimal quantity=product.getQuantity();//数量
			List<OutSeriVO> serials=product.getSerials();//串码信息
			if(null==supplyid){
				return Pub.returnInfo(ss.getOutcode(), -1, "失败：供应商"+supplyid+"为空", null);
			}
			String sql="select name from supply where id=?";
			Object[] parms=new Object[]{supplyid};
			logger.debug("查询sql："+Pub.logSQL(sql, parms));
			List<String> list = baseDao.getList( sql, parms,"name");
			if(null==list||list.size()==0)return Pub.returnInfo(ss.getOutcode(), -1, "失败：供应商"+supplyid+"不存在", null);
			/**
			 * 仓库是否存在供应商
			 */
			String comSql=" select sp.id from store_product sp where sp.pk_stordoc=? and sp.productid=?  ";
			Object[] comParms=new Object[]{pk_store,productcode};
			List<String> comList=baseDao.getList( comSql, comParms,"id");
			logger.debug("查询sql："+Pub.logSQL(comSql, comParms));
			if(null==comList||comList.size()==0)return Pub.returnInfo(ss.getOutcode(), -1, "失败：仓库"+pk_store+"不存在产品"+productcode+"", null);
			String str= checkProduct(ss, baseDao, productcode,quantity,serials, pk_store,supplyid);
			if(null!=str)return str;
		}
		return null;
	}

//	private List<String> getList(PubBaseDao baseDao, String sql, Object[] parms,final String name) {
//		List<String> list=baseDao.getJdbcTemplate().query(sql, parms, new RowMapper<String>(){
//			@Override
//			public String mapRow(ResultSet rs, int i)throws SQLException {
//				return rs.getString(name);
//			}
//		});
//		return list;
//	}
	
	/***
	 * 检查产品
	 * @param ss
	 * @param baseDao
	 * @return
	 */
	public String checkProduct(OutStoreAggVO ss,PubBaseDao baseDao,String productcode,BigDecimal quantity,List<OutSeriVO> serials,String pk_store,BigDecimal supplyid){
		if(null==productcode)return Pub.returnInfo(ss.getOutcode(), -1, "失败：产品信息为空", null);
		String sql=" select productid from product_main where productid=? ";
		Object[] parms=new Object[]{productcode};
		logger.debug("查询sql："+Pub.logSQL(sql, parms));
		List<String> list = baseDao.getList( sql, parms,"productid");
		if(null==list||list.size()==0)return Pub.returnInfo(ss.getOutcode(), -1, "失败：产品"+productcode+"不存在", null);//产品不能为空
		if(null==quantity)return Pub.returnInfo(ss.getOutcode(), -1, "失败：产品数量为空", null);//产品数量不能为空
		String productid=list.get(0);//产品数量
		//检查产品数量
		String sqlstore=" select allocatable from store_product where pk_stordoc=? and productid=? and supplyid=?";
		Object[] ps=new Object[]{pk_store,productid,supplyid};
		logger.debug("查询sql："+Pub.logSQL(sqlstore, ps));
		List<String> lt=baseDao.getList(sqlstore, ps,"allocatable");
		if(quantity.compareTo(new BigDecimal(lt.get(0)))>=0)return Pub.returnInfo(ss.getOutcode(), -1, "失败：产品"+productcode+" 数量: "+quantity+" 大于库存数量  "+lt.get(0), null);
		//if(null==serials||serials.size()==0)return Pub.returnInfo(ss.getOutcode(), -1, "失败：串码信息为空", null);
		if(serials != null && serials.size() > 0){
			String sers=checkSerials(baseDao, ss.getOutcode(), serials, quantity, productcode);
			if(null!=sers)return sers;
		}
		//更新库存sql
		String updatesql=" update store_product set allocatable=allocatable-"+quantity+" where pk_stordoc='"+pk_store+"' and productid="+productid+" ";
		updateList.add(updatesql);
		//检查串码
		return null;
	}
	
	/***
	 * 校验串码数量与产品数量相同
	 * @param baseDao 数据库实例
	 * @param ordercode 订单号
	 * @param serials 串码
	 * @param quantity 数量
	 * @return
	 */
	public String checkSerials(PubBaseDao baseDao,String ordercode,List<OutSeriVO> serials,BigDecimal quantity,String productcode){
		if(quantity.compareTo(new BigDecimal(serials.size()))!=0)return Pub.returnInfo(ordercode, -1, "失败：产品"+productcode+"数量与串码数量不同", null);
		return null;
	}
	
	/***
	 * 添加厂家出库记录
	 * @param aggvo
	 * @param baseDao
	 * @return
	 */
	public boolean addOutStore(OutStoreAggVO aggvo,PubBaseDao baseDao){
		return false;
	}

	/***
	 * 更新库存
	 * @return
	 */
	public boolean changeStore(PubBaseDao baseDao) {
		if(updateList.size()==0)return false;
		String[] sql=new String[updateList.size()];
		sql=updateList.toArray(sql);
		updateList.clear();
		int[] rows=baseDao.getJdbcTemplate().batchUpdate(sql);//更新库存
		return rows.length>0?true:false;
	}

}
